/**************************************************************************
 *   node.h                                                               *
 *                                                                        *
 *   Copyright (C) 2009 Paul Tagliamonte ( paultag@ubuntu.com )           *
 *   This program is free software; you can redistribute it and/or modify *
 *   it under the terms of the GNU General Public License as published by *
 *   the Free Software Foundation; either version 1, or (at your option)  *
 *   any later version.                                                   *
 *                                                                        *
 *   This program is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of       *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
 *   GNU General Public License for more details.                         *
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
 *   along with this program; if not, write to the Free Software          *
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
 *                                                                        *
 **************************************************************************/

#ifndef _NODE_H
#define _NODE_H INC

#include <vector>
#include "hypo.h"
#include "runnable.h"


class node : public runnable {
	private:
	int                    status;
	int                    flags;

	bool HeteroStatus; // This notes that the node wants to have a different status then it's peers.

	std::vector <hypo *> * HypoList;

	std::vector <node *> * LinkedNodes;
	std::vector <node *> * LinkingNodes;

	public:

	/*
	 * Constructor, Creates a node with count Hypos
	 * that will be used to rate all status values of the node.
	 */
	node ( int count ) {
		this->status = 0;
		this->flags  = 0;

		this->HypoList     = new std::vector<hypo *>();
		this->LinkedNodes  = new std::vector<node *>();
		this->LinkingNodes = new std::vector<node *>();

		this->HeteroStatus = true;

		for ( int i = 0; i < count; ++i ) {
			this->HypoList->push_back( new hypo( i ) );
		}
	}

	/*
	 * linkNode takes a single node pointer to link to this node. This node, in return will mark it's self on the other node.
	 */
	void linkNode( node * n ) {
		if ( n != NULL && n != this ) {
			this->LinkedNodes->push_back( n );
			n->iAmLinking( this );
		}
	}

	/*
	 * Warning: This method should not be called from god. It is the Node's duty.
	 * Really. You can Eff things up.
	 * ( Haha, doodey )
	 */
	void iAmLinking( node * n ) {
		if ( n != NULL && n != this ) {
			this->LinkingNodes->push_back( n );
		}
	}

	/*
	 * getStatus returns the current node status.
	 */
	int getStatus() {
		return this->status;
	}

	/*
	 * setHeteroStatus takes a single boolean for it's internal will to either attract to like nodes, or
	 * to work to differ then their peers.
	 */
	void setHeteroStatus( bool s ) {
		this->HeteroStatus = s;
	}

	/*
	 * isComplete returns if the node is happy in it's current decision,
	 * this verifies that the node follows the rules.
	 */
	bool isComplete() {
		bool ret     = true;

		node * n;

		for ( unsigned int i = 0; i < this->LinkedNodes->size(); ++i ) {
			n = this->LinkedNodes->at(i);
			if ( ( n->getStatus() == this->getStatus() ) && this->HeteroStatus ) {
				ret = false;
			} else if ( ( n->getStatus() != this->getStatus() ) && ! this->HeteroStatus ) {
				ret = false;
			}
		}

		return ret;
	}

	/*
	 * This here is the majik Run method.
	 * This is the entry point for my runnable superclass.
	 * Put any logic that should be run multithreaded when start() is called
	 * here. This is such a sweet function, all hail it's bits.
	 */
	virtual void run() {
		std::cout << "Node Active\n";
		usleep( 1000000 );
		std::cout << "Node Away!\n";
	}

};

#endif
